#include "STC8H.H"
#include "MATH.H"
#include "stdio.h"
#include "INTRINS.H"
#include "configuration.h"
#include "../ADC/ADC.h"
#include "../PWM/PWM.h"
#include "../LED/LED.h"
#include "../KEY/KEY.h"
#include "../storage/storage.h"


/*************************************************/
#define _temp_control_ 0           //温控模式
#define _manual_ 1                 //手动模式

#define menu_l0 0               //根菜单
#define menu_l1 1               //一级菜单
#define menu_l2 2               //二级菜单
#define menu_l3 3               //三级菜单

/*********************函数声明************************/
void menu_0(char data key);
void menu_1(char data key);
void menu_2(char data key);
void menu_3(char data key);
void menu_4(char data key);
void menu_5(char data key);
void menu_7(char data key);
void menu_8(char data key);
void menu_10(char data key);
void menu_12(char data key);
void menu_13(char data key);
void menu_15(char data key);
void menu_16(char data key);
void menu_18(char data key);
void menu_19(char data key);

void menu_settings_init();
void delay_ms(unsigned int data i);
void Timer0_Init(void);

/*****************全局变量定义******************/
setting settings;                    //全部设置变量

unsigned char data i=0;               //当前菜单

unsigned char data _temp;                               //当前温度
unsigned char data _temp0;                           //缓存温度
unsigned char data _control_point_count;             //控制点计数
unsigned char data _display_on;          //显示开关
unsigned char data _5000ms_ok=0;          
unsigned char data _10ms_ok=0;      //按键检测标志
unsigned char data _1000ms_ok=0;      //1s计时标志
unsigned char data _30000ms_ok=0;      //30s计时标志
/*******************结构体定义******************************/
code setting_addr settings_addr=
{
    {
        {
        {0x0000,0x0001,0x0002},{0x0003,0x0004,0x0005},{0x0006,0x0007,0x0008},{0x0009,0x000a,0x000b},
        {0x000c,0x000d,0x000e},{0x000f,0x0010,0x0011},{0x0012,0x0013,0x0014},
        {0x0015,0x0016,0x0017},{0x0018,0x0019,0x001a},{0x001b,0x001c,0x001d}
        }
    },
    {
        0x001e,
        0x001f
    },
    0x0020,
    {
        0x0021,
        0x0022
    },
    {
        0x0023,
        0x0024
    },
    {
        0x0025,
        0x0026
    },
    _settings_dat_count_
};

setting_menu menu[]=
{
    menu_l0,                    //0
    _0_,_0_,                                     //温度转换字码
    NULL,                                    //当前温度读数/弃用
    menu_0,
            menu_l1,            //1
            _F_,_0_,                            //温控曲线设置，显示F0
            NULL,
            menu_1,
                    menu_l2,            //2
                    _P_,NULL,                      //曲线设置，显示P[i]
                    NULL,
                    menu_2, 
                            menu_l3,        //3        //控制点en 
                            NULL,NULL,                     
                            NULL,                           
                            menu_3,

                            menu_l3,     //4       //控制点温度
                            NULL,NULL,                     
                            NULL,                     
                            menu_4,

                            menu_l3,     //5       //控制点pwm
                            NULL,NULL,       
                            NULL,         
                            menu_5,
                    
            menu_l1,                //6
            _F_,_1_,                          //风扇关停设置，显示F1
            NULL,
            NULL,
                            menu_l3,        //7                    //自动关停开关
                            NULL,NULL,                     
                            NULL,                              
                            menu_7,

                            menu_l3,        //8                     //关停温度
                            NULL,NULL,              
                            NULL,                         
                            menu_8,

            menu_l1,                    //9
            _F_,_2_,                                       //pwm控制模式，显示F2
            NULL,
            NULL,
                            menu_l3,         //10                       //控制模式数据
                            NULL,NULL,            
                            NULL,                   
                            menu_10,

            menu_l1,               //11                      //温控延迟
            _F_,_3_,                           //温控延迟，显示F3
            NULL,
            NULL,
                            menu_l3,         //12                   //温控延迟mode
                            NULL,NULL,          
                            NULL,                
                            menu_12,

                            menu_l3,         //13                       //温控hys
                            NULL,NULL,              
                            NULL,               
                            menu_13,
            menu_l1,                        //14
            _F_,_4_,                                        //显示设置，显示F4
            NULL,
            NULL,
                            menu_l3,         //15           //常亮开关always
                            NULL,NULL,                  
                            NULL,                              
                            menu_15,

                            menu_l3,         //16           //亮度
                            NULL,NULL,                      
                            NULL,
                            menu_16,
            menu_l1,                          //17
            _F_,_5_,                                                       //控制模式设置 0自动   1手动，显示F5
            NULL,
            NULL,
                            menu_l3,            //18        //控制模式数据   AU：0     OF：1  
                            NULL,NULL,                 
                            NULL,                       
                            menu_18,

                            menu_l3,           //19         //手动模式pwm数据
                            NULL,NULL,             
                            NULL,                      
                            menu_19

};
/***************************************/
/*#########################函数定义###################################*/
void gpio_init()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;//0xff;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;//0xff;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    // P1DR = 0x00;
    // P3DR = 0x00;
}
/********************************设置初始化**************************************/
void settings_init()
{
    char data i;
    char data j;
    for (i=0;i<10;i++)
    {
        settings.f0.l[i].en=read_storage(settings_addr.f0.l[i].en);
        settings.f0.l[i].temp=read_storage(settings_addr.f0.l[i].temp);
        settings.f0.l[i].duty=read_storage(settings_addr.f0.l[i].duty);
    }
    settings.f1.en=read_storage(settings_addr.f1.en);
    settings.f1.temp=read_storage(settings_addr.f1.temp);
    settings.f2=read_storage(settings_addr.f2);
    settings.f3.mode=read_storage(settings_addr.f3.mode);
    settings.f3.hys=read_storage(settings_addr.f3.hys);
    settings.f4.always=read_storage(settings_addr.f4.always);
    settings.f4.brightness=read_storage(settings_addr.f4.brightness);
    settings.f5.mode=read_storage(settings_addr.f5.mode);
    settings.f5.duty=read_storage(settings_addr.f5.duty);

    _control_point_count=0;
    for(j=0;j<10;j++)
    {
        if(settings.f0.l[j].en)
        {
            _control_point_count++;
        }
    }
    menu_settings_init();
}
/*******菜单变量初始化*******/
void menu_settings_init()
{
menu[auto_off_en].buf=settings.f1.en;
    switch (menu[auto_off_en].buf)
    {
    case 0:
        menu[auto_off_en].dis_tenth=_0_;
        menu[auto_off_en].dis_dig=_F_;
        break;
    
    case 1:
        menu[auto_off_en].dis_tenth=_0_;
        menu[auto_off_en].dis_dig=_n_;
        break;
    }
menu[auto_off_temp].buf=settings.f1.temp;
    menu[auto_off_temp].dis_tenth=menu[auto_off_temp].buf/10;
    menu[auto_off_temp].dis_dig=menu[auto_off_temp].buf%10;
menu[pwm_mode].buf=settings.f2;
    menu[pwm_mode].dis_tenth=_dig_off_;
    menu[pwm_mode].dis_dig=menu[pwm_mode].buf;
menu[hys_mode].buf=settings.f3.mode;
    switch (menu[hys_mode].buf)
    {
    case 0:
        menu[hys_mode].dis_tenth=_0_;
        menu[hys_mode].dis_dig=_F_;
        break;
    
    case 1:
        menu[hys_mode].dis_tenth=_dig_off_;
        menu[hys_mode].dis_dig=_U_;
        break;
    case 2:
        menu[hys_mode].dis_tenth=_dig_off_;
        menu[hys_mode].dis_dig=_d_;
        break;
    case 3:
        menu[hys_mode].dis_tenth=_U_;
        menu[hys_mode].dis_dig=_d_;
        break;

    }
menu[hys_temp].buf=settings.f3.hys;
    menu[hys_temp].dis_tenth=menu[hys_temp].buf/10;
    menu[hys_temp].dis_dig=menu[hys_temp].buf%10;
menu[dis_al_on].buf=settings.f4.always;
    switch(menu[dis_al_on].buf)
    {
    case 0:
        menu[dis_al_on].dis_tenth=_0_;
        menu[dis_al_on].dis_dig=_F_;
        break;
    case 1:
        menu[dis_al_on].dis_tenth=_0_;
        menu[dis_al_on].dis_dig=_n_;
        break;
    }
menu[dis_brightness].buf=settings.f4.brightness;
    menu[dis_brightness].dis_tenth=_dig_off_;
    menu[dis_brightness].dis_dig=menu[dis_brightness].buf;
menu[manual_en].buf=settings.f5.mode;
    switch(menu[manual_en].buf)
    {
    case 0:
        menu[manual_en].dis_tenth=_0_;
        menu[manual_en].dis_dig=_F_;
        break;
    case 1:
        menu[manual_en].dis_tenth=_0_;
        menu[manual_en].dis_dig=_n_;
        break;
    }
menu[manual_duty].buf=settings.f5.duty;
    menu[manual_duty].dis_tenth=menu[manual_duty].buf/10;
    menu[manual_duty].dis_dig=menu[manual_duty].buf%10;

}
/********************************从菜单装载设置************************************/
 /*void settings_menu_init()
{
    char data i;
    char data j;
    i=menu[control_point].buf;
    
        settings.f0.l[i].en=menu[l_en].buf;
        settings.f0.l[i].temp=menu[l_temp].buf;
        settings.f0.l[i].duty=menu[l_duty].buf;
    
    settings.f1.en=menu[auto_off_en].buf;
    settings.f1.temp=menu[auto_off_temp].buf;
    settings.f2=menu[pwm_mode].buf;
    settings.f3.mode=menu[hys_mode].buf;
    settings.f3.hys=menu[hys_temp].buf;
//    settings.f3.hys_down=read_storage(settings_addr.f3.hys_down);
    settings.f4.always=menu[dis_al_on].buf;
    settings.f4.brightness=menu[dis_brightness].buf;
    settings.f5.mode=menu[manual_en].buf;
    settings.f5.duty=menu[manual_duty].buf;
    _control_point_count=0;
    for(j=0;j<10;j++)
    {
        if(settings.f0.l[j].en)
        {
            _control_point_count++;
        }
    }
}*/
/*********************************************/
void _temp_controller()
{
    if(settings.f1.en&&(_temp<=settings.f1.temp))
    {
        fan_en=_OFF_;
    }else{fan_en=_ON_;}


        
        switch (settings.f3.mode)
        {
        case _OFF_:
            pwm_adj();
            _temp0=_temp;                           //防止模式切换出错
            break;
        
        case _HYS_UD_:
            
            if(abs(_temp-_temp0)>=settings.f3.hys)
            {
                pwm_adj();
                _temp0=_temp;
            }
            break;
        case _HYS_U_:
            switch (_temp-_temp0>=0)
            {
            case 1:
                if(_temp-_temp0>=settings.f3.hys)
                {
                    pwm_adj();
                    _temp0=_temp;
                }
                break;
            
            case 0:
                pwm_adj();
                _temp0=_temp;
                break;
            }
            break;
        case _HYS_D_:
            switch (_temp0-_temp>=0)
            {
            case 1:
                if(_temp0-_temp>=settings.f3.hys)
                {
                    pwm_adj();
                    _temp0=_temp;
            
                }
                break;
            
            case 0:
                pwm_adj();
                _temp0=_temp;
                break;
            }
            break;
        }
        
}

/*****************************/

void key_response()                                     //按键响应，包含温度显示
{
    unsigned char data _key;

 //   unsigned char j;              //菜单等级缓存   
    _key=read_key();

    switch(_display_on)
    {
    case 1:
        if((!settings.f4.always)&&_5000ms_ok&&(i==_root_)){_display_on=0;}           //5s关闭显示
        if(i>0&&_30000ms_ok)                 //30s后关闭菜单，从设置更新以重置菜单参数
        {
            menu_settings_init();
            //_display_on=0;
            shumaguan_shi_shanshuo_en=_ON_;
            shumaguan_ge_shanshuo_en=_ON_;
            delay_ms(500);
            shumaguan_shi_shanshuo_en=_OFF_;
            shumaguan_ge_shanshuo_en=_OFF_;
            //_display_on=1;
            i=0;
        }else if(_key!=n_key)
        {
            switch(menu[i].menu_l)
            {
            case menu_l0:
                _5000ms_ok=0;
                break;
            case menu_l1:
            case menu_l2:
            case menu_l3:
                _30000ms_ok=0;
                break;
            }
            switch(_key)
            {
            case s_tap:
                switch(menu[i].menu_l)
                {
                case menu_l1:
                    if(menu[i].func!=NULL){menu[i].func(_key);}         //执行功能函数
                    while(menu[++i].menu_l!=menu_l1)
                    {
                        if(i>=_menu_count_-1)
                        {
                            i=0;
                        }
                    }
                    break;
                case menu_l0:
                case menu_l2:
                case menu_l3:
                    if(menu[i].func!=NULL){menu[i].func(_key);}         //执行功能函数
                    break;

                }
                break;
            case d_tap:
                switch(menu[i].menu_l)
                {
                case menu_l1:
                    if(menu[i].func!=NULL){menu[i].func(_key);}         //执行功能函数
                    i=_root_;
                    break;
                case menu_l2:
                    if(menu[i].func!=NULL){menu[i].func(_key);}         //执行功能函数
                    
                    break;
                case menu_l0:
                case menu_l3:
                    if(menu[i].func!=NULL){menu[i].func(_key);}         //执行功能函数
                    break;
                }
                break;
            case l_press:                   
                switch(menu[i].menu_l)
                {

                case menu_l3:
                case menu_l2:
                    if(menu[i].func!=NULL){menu[i].func(_key);}         //执行功能函数
                    break;
                case menu_l0:
                case menu_l1:
                
                    if(menu[i].func!=NULL){menu[i].func(_key);}         //执行功能函数
                    i++;
                    break;
                }
                break;
            }

        }
        if(i==_root_){menu[_root_].func(n_key);}                            //刷新温度显示参数
        display(menu[i].dis_tenth,menu[i].dis_dig);     //显示刷新
        _5000ms_ok=0;               //显示休眠计时
        break;
    case 0:
        if(settings.f4.always)
        {
            _display_on=1;
        }else if((_key!=n_key)&&(i==_root_))
        {
            _display_on=1;
            _5000ms_ok=0;
        }
        break;
    }
 
    


    
    
}

/************************************************/
void main_thread()
{
    i=0;
    _temp=read_temp();
    _temp0=_temp;                   //初始化温度缓存

    while(1)
    {
        

        if(_1000ms_ok)
        {
            _1000ms_ok=0;
            _temp=read_temp();
            if(settings.f5.mode==_temp_control_)
            {
                _temp_controller();             //温控
            }
            


        }
        key_detect();                   //按键扫描驱动

        key_response();                //响应按键操作，每次只处理一个按键操作
    }
}
/****************************************************************/
void main()                                      //定时1s检测温度，设置pwm占空比
{
    _display_on=_OFF_;              //关闭显示
    gpio_init();                                //io初始化
    sc_init(500);                                   //测速信号模拟
    settings_init();                                //读取设置参数,包括亮度
    display_init();                             //显示初始化
    /**************恢复出厂****************/
    if(!key_input)
    {
        delay_ms(1000);
        if(!key_input)
        {
            delay_ms(1000);
                if(!key_input)
                {
                    delay_ms(1000);
                    if(!key_input)
                    {
                        factory_reset();
                        display(_8_,_8_);
                        _display_on=_ON_;
                        shumaguan_shi_shanshuo_en=1;
                        shumaguan_ge_shanshuo_en=1;
                        shumaguan_shanshuo=shumaguan_shanshuo_quick;
                        delay_ms(5000);
                        shumaguan_shi_shanshuo_en=0;
                        shumaguan_ge_shanshuo_en=0;
                        _display_on=_OFF_;              //关闭显示
                        gpio_init();                                //io初始化
                        sc_init(500);                                   //测速信号模拟
                        settings_init();                                //读取设置参数,包括亮度
                        display_init();                             //显示初始化
                    }
                }
        }

    }


    /******************恢复出厂******************/

    _display_on=_ON_;               //读取正确亮度   开显示
    _5000ms_ok=0;                   //第一次休眠计时
    ADC_init();                                  //adc初始化
    pwm_init();                                 //pwm初始化


    main_thread();                                  //主线程
while(1);
}
/********************************************/
void Timer0_Init(void)		//833微秒@33.1776MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x0b;				//设置定时初始值
	TH0 = 0x94;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
    ET0=1;          //定时器中断
    EA=1;               //总中断
}
/*************************菜单功能函数*************************/
void delay_ms(unsigned int data x)
{	
    unsigned char data i, j;
    for(;x>0;x--)
    {
        

        _nop_();
        _nop_();
        i = 44;
        j = 19;
        do
        {
            while (--j);
        } while (--i);
    }

}

void menu_0(char data key)          //根菜单
{
    menu[0].dis_tenth=_temp/10;
    if(menu[0].dis_tenth==0)
    {
        menu[0].dis_tenth=_dig_off_;
    }
    menu[0].dis_dig=_temp%10;
}
void menu_1(char data key)          //F0
{
    switch(key)
    {
    case l_press:
        menu[control_point].buf=0;
        menu[control_point].dis_tenth=_P_;
        menu[control_point].dis_dig=menu[control_point].buf;
        break;
    case d_tap:
        i=_root_;
        break;
    }
}
void menu_2(char data key)          //P
{
    char j;
    switch(key)
    {
    case s_tap:
        if(++menu[i].buf>9)
        {
            menu[i].buf=0;
        }
        menu[i].dis_dig=menu[i].buf;
        break;
    case d_tap:
        i=f0_temp_control;
        break;
    case l_press:
        switch(settings.f0.l[menu[control_point].buf].en)
        {
        case 0:
            j=0;
            while(settings.f0.l[j].en&&j<10)
            {
                j++;
            }
            menu[control_point].buf=j;
            break;
        case 1:
            break;
        }
        menu[l_en].buf=settings.f0.l[menu[control_point].buf].en;
        switch(menu[l_en].buf)
        {
        case 0:
            menu[l_en].dis_tenth=_0_;
            menu[l_en].dis_dig=_F_;
            break;
        case 1:
            menu[l_en].dis_tenth=_0_;
            menu[l_en].dis_dig=_n_;
            break;
        }
        i=l_en;
        break;
    }
}
void menu_3(char data key)          //l_en
{
    switch(key)
    {
    case s_tap:
        menu[l_en].buf=!menu[l_en].buf;
        switch(menu[l_en].buf)
        {
        case 0:
            menu[l_en].dis_tenth=_0_;
            menu[l_en].dis_dig=_F_;
            break;
        case 1:
            menu[l_en].dis_tenth=_0_;
            menu[l_en].dis_dig=_n_;
            break;
        }
        break;
    case d_tap:
        i=control_point;
        break;
    case l_press:
        menu[l_temp].buf=settings.f0.l[menu[control_point].buf].temp;
        menu[l_temp].dis_tenth=menu[l_temp].buf/10;
        menu[l_temp].dis_dig=menu[l_temp].buf%10;

        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(500);   
        shumaguan_shanshuo=shumaguan_shanshuo_slow;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_OFF_;

        i=l_temp;
        break;


    }
}
void menu_4(char data key)          //l_temp
{
    
    switch(key)
    {
    case s_tap:
        switch(shumaguan_shi_shanshuo_en>shumaguan_ge_shanshuo_en)
        {
        case 0:
            if(++menu[l_temp].dis_dig>9)
            {
                menu[l_temp].dis_dig=0;
            }
            break;
        case 1:
            if(++menu[l_temp].dis_tenth>9)
            {
                menu[l_temp].dis_tenth=0;
            }
            break;
        }
        menu[l_temp].buf=menu[l_temp].dis_tenth*10+menu[l_temp].dis_dig;
        break;
    case d_tap:
        shumaguan_shi_shanshuo_en=!shumaguan_shi_shanshuo_en;
        shumaguan_ge_shanshuo_en=!shumaguan_ge_shanshuo_en;
        break;
    case l_press:
        menu[l_duty].buf=settings.f0.l[menu[control_point].buf].duty;
        menu[l_duty].dis_tenth=menu[l_duty].buf/10;
        menu[l_duty].dis_dig=menu[l_duty].buf%10;

        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(500);

        shumaguan_shanshuo=shumaguan_shanshuo_slow;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_OFF_;
        i=l_duty;
        break;
    }
}
void menu_5(char data key)          //l_duty
{
    
    switch(key)
    {
    case s_tap:
        switch(shumaguan_shi_shanshuo_en>shumaguan_ge_shanshuo_en)
        {
        case 0:
            if(++menu[l_duty].dis_dig>9)
            {
                menu[l_duty].dis_dig=0;
            }
            break;
        case 1:
            if(++menu[l_duty].dis_tenth>9)
            {
                menu[l_duty].dis_tenth=0;
            }
            break;
        }
        menu[l_duty].buf=menu[l_duty].dis_tenth*10+menu[l_duty].dis_dig;
        break;
    case d_tap:
        shumaguan_shi_shanshuo_en=!shumaguan_shi_shanshuo_en;
        shumaguan_ge_shanshuo_en=!shumaguan_ge_shanshuo_en;
        break;
        
    case l_press:
        before_update(settings_addr.f0.l[menu[control_point].buf].en,3);
        write_storage(settings_addr.f0.l[menu[control_point].buf].en,menu[l_en].buf);
        write_storage(settings_addr.f0.l[menu[control_point].buf].temp,menu[l_temp].buf);
        write_storage(settings_addr.f0.l[menu[control_point].buf].duty,menu[l_duty].buf);
        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(1000);
        shumaguan_shi_shanshuo_en=_OFF_;
        shumaguan_ge_shanshuo_en=_OFF_;
        i=_root_;
        break;

    }
}
void menu_7(char data key)          //auto_off_en
{
    switch(key)
    {
    case s_tap:
        menu[auto_off_en].buf=!menu[auto_off_en].buf;
        switch(menu[auto_off_en].buf)
        {
        case 0:
            menu[auto_off_en].dis_tenth=_0_;
            menu[auto_off_en].dis_dig=_F_;
            break;
        case 1:
            menu[auto_off_en].dis_tenth=_0_;
            menu[auto_off_en].dis_dig=_n_;
            break;
        }
        break;
    case d_tap:
        i=f1_auto_off;
        break;
    case l_press:

        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(500);

        shumaguan_shanshuo=shumaguan_shanshuo_slow;
        shumaguan_ge_shanshuo_en=_OFF_;
        shumaguan_shi_shanshuo_en=_ON_;
        
        i=auto_off_temp;
        break;
    }
}
void menu_8(char data key)          //auto_off_temp
{
    switch(key)
    {
    case s_tap:
        switch(shumaguan_shi_shanshuo_en>shumaguan_ge_shanshuo_en)
        {
        case 0:
            if(++menu[auto_off_temp].dis_dig>9)
            {
                menu[auto_off_temp].dis_dig=0;
            }
            break;
        case 1:
            if(++menu[auto_off_temp].dis_tenth>9)
            {
                menu[auto_off_temp].dis_tenth=0;
            }
            break;
        }
        menu[auto_off_temp].buf=menu[auto_off_temp].dis_tenth*10+menu[auto_off_temp].dis_dig;
        break;
    case d_tap:
        shumaguan_ge_shanshuo_en=!shumaguan_ge_shanshuo_en;
        shumaguan_shi_shanshuo_en=!shumaguan_shi_shanshuo_en;
        break;
    case l_press:
        before_update(settings_addr.f1.en,2);
        write_storage(settings_addr.f1.en,menu[auto_off_en].buf);
        write_storage(settings_addr.f1.temp,menu[auto_off_temp].buf);
        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(1000);
        shumaguan_shi_shanshuo_en=_OFF_;
        shumaguan_ge_shanshuo_en=_OFF_;
        i=_root_;
        break;
    }
}
void menu_10(char data key)         //pwm_mode
{
    switch(key)
    {
    case s_tap:
        if(++menu[pwm_mode].buf>2){menu[pwm_mode].buf=0;}
        menu[pwm_mode].dis_dig=menu[pwm_mode].buf;
        break;
    case d_tap:
        i=f2_pwm_mode;
        break;
    case l_press:
        before_update(settings_addr.f2,1);
        write_storage(settings_addr.f2,menu[pwm_mode].buf);
        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(1000);
        shumaguan_shi_shanshuo_en=_OFF_;
        shumaguan_ge_shanshuo_en=_OFF_;
        i=_root_;
        break;
    }

}
void menu_12(char data key)         //hys_mode
{
    switch(key)
    {
    case s_tap:
        if(++menu[hys_mode].buf>3){menu[hys_mode].buf=0;}
        switch(menu[hys_mode].buf)
        {
        case 0:
            menu[hys_mode].dis_tenth=_0_;
            menu[hys_mode].dis_dig=_F_;
            break;
        case 1:
            menu[hys_mode].dis_tenth=_dig_off_;
            menu[hys_mode].dis_dig=_U_;
            break;
        case 2:
            menu[hys_mode].dis_tenth=_dig_off_;
            menu[hys_mode].dis_dig=_d_;
            break;
        case 3:
            menu[hys_mode].dis_tenth=_U_;
            menu[hys_mode].dis_dig=_d_;
            break;
        }
        break;
    case d_tap:
        i=f3_hys_set;
        break;
    case l_press:

        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(500);

        shumaguan_shanshuo=shumaguan_shanshuo_slow;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_OFF_;
        
        i=hys_temp;
        break;

    }

}
void menu_13(char data key)         //hys_temp
{
    switch(key)
    {
    case s_tap:
        switch(shumaguan_shi_shanshuo_en>shumaguan_ge_shanshuo_en)
        {
        case 0:
            if(++menu[hys_temp].dis_dig>9)
            {
                menu[hys_temp].dis_dig=0;
            }
            break;
        case 1:
            if(++menu[hys_temp].dis_tenth>9)
            {
                menu[hys_temp].dis_tenth=0;
            }
            break;
        }
        menu[hys_temp].buf=menu[hys_temp].dis_tenth*10+menu[hys_temp].dis_dig;
        break;
    case d_tap:
        shumaguan_ge_shanshuo_en=!shumaguan_ge_shanshuo_en;
        shumaguan_shi_shanshuo_en=!shumaguan_shi_shanshuo_en;
        break;
    case l_press:
        before_update(settings_addr.f3.mode,2);
        write_storage(settings_addr.f3.mode,menu[hys_mode].buf);
        write_storage(settings_addr.f3.hys,menu[hys_temp].buf);
        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(1000);
        shumaguan_shi_shanshuo_en=_OFF_;
        shumaguan_ge_shanshuo_en=_OFF_;
        i=_root_;
        break;

    }
}
void menu_15(char data key)         //dis_al_on
{
    switch(key)
    {
    case s_tap:
        menu[dis_al_on].buf=!menu[dis_al_on].buf;
        switch(menu[dis_al_on].buf)
        {
        case 0:
            menu[dis_al_on].dis_tenth=_0_;
            menu[dis_al_on].dis_dig=_F_;
            break;
        case 1:
            menu[dis_al_on].dis_tenth=_0_;
            menu[dis_al_on].dis_dig=_n_;
            break;
        }
        break;
    case d_tap:
        i=f4_dis_set;
        break;
    case l_press:
        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(500);
        shumaguan_ge_shanshuo_en=_OFF_;
        shumaguan_shi_shanshuo_en=_OFF_;
        i=dis_brightness;
        break;
    }
}
void menu_16(char data key)         //dis_brightness
{
    switch(key)
    {
    case s_tap:
        if(++menu[dis_brightness].buf>5){menu[dis_brightness].buf=1;}
        menu[dis_brightness].dis_dig=menu[dis_brightness].buf;
        _brightness=menu[dis_brightness].buf;
        break;
    case d_tap:
        _brightness=settings.f4.brightness;
        i=f4_dis_set;
        break;
    case l_press:
        before_update(settings_addr.f4.always,2);
        write_storage(settings_addr.f4.always,menu[dis_al_on].buf);
        write_storage(settings_addr.f4.brightness,menu[dis_brightness].buf);
        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(1000);
        shumaguan_shi_shanshuo_en=_OFF_;
        shumaguan_ge_shanshuo_en=_OFF_;
        i=_root_;
        break;
    }
}
void menu_18(char data key)         //manual_en
{
    switch(key)
    {
    case s_tap:
        menu[manual_en].buf=!menu[manual_en].buf;
        switch(menu[manual_en].buf)
        {
        case 0:
            menu[manual_en].dis_tenth=_0_;
            menu[manual_en].dis_dig=_F_;
            break;
        case 1:
            menu[manual_en].dis_tenth=_0_;
            menu[manual_en].dis_dig=_n_;
            break;
        }
        break;
    case d_tap:
        i=f5_manual;
        break;
    case l_press:

        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(500);

        shumaguan_shanshuo=shumaguan_shanshuo_slow;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_OFF_;
        
        i=manual_duty;
        break;
    }
}
void menu_19(char data key)         //manual_duty
{
    switch(key)
    {
    case s_tap:
        switch(shumaguan_shi_shanshuo_en>shumaguan_ge_shanshuo_en)
        {
        case 0:
            if(++menu[manual_duty].dis_dig>9)
            {
                menu[manual_duty].dis_dig=0;
            }
            break;
        case 1:
            if(++menu[manual_duty].dis_tenth>9)
            {
                menu[manual_duty].dis_tenth=0;
            }
            break;
        }
        menu[manual_duty].buf=menu[manual_duty].dis_tenth*10+menu[manual_duty].dis_dig;
        break;
    case d_tap:
        shumaguan_ge_shanshuo_en=!shumaguan_ge_shanshuo_en;
        shumaguan_shi_shanshuo_en=!shumaguan_shi_shanshuo_en;
        break;
    case l_press:
        before_update(settings_addr.f5.mode,2);
        write_storage(settings_addr.f5.mode,menu[manual_en].buf);
        write_storage(settings_addr.f5.duty,menu[manual_duty].buf);
        shumaguan_shanshuo=shumaguan_shanshuo_quick;
        shumaguan_shi_shanshuo_en=_ON_;
        shumaguan_ge_shanshuo_en=_ON_;
        delay_ms(1000);
        shumaguan_shi_shanshuo_en=_OFF_;
        shumaguan_ge_shanshuo_en=_OFF_;
        i=_root_;
        break;

    }
}

void Timer0_Isr(void) interrupt 1                   //中断函数
{
    static unsigned int data _5000ms_count=0;
    static unsigned char data _10ms_count=0;
    static unsigned int data _1000ms_count=0;
    static unsigned int data _30000ms_count=0;
    display_driver();
    if (++_10ms_count>20)
    {
        _10ms_count=0;
        _10ms_ok=1;                             //按键监测标志位
    }
    if(++_1000ms_count>1200)
    {
        _1000ms_count=0;
        _1000ms_ok=1;
    }
    if(!_5000ms_ok)
    {
        if(++_5000ms_count>6000)
        {
            _5000ms_count=0;
            _5000ms_ok=1;
        }
    }
    if(!_30000ms_ok)
    {
        if(++_30000ms_count>36000)
        {
            _30000ms_count=0;
            _30000ms_ok=1;
        }
    }  
}